﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace PokerService
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
    public class GameService : ILogin, IPortal, IGame
    {
        List<Player> playerList;
        List<Table> tableList;
        List<Move> moveList;

        public GameService()
        {
            //Players
            playerList = new List<Player>();
            playerList.Add(new Player("a", "a", 50, 0, false));
            playerList.Add(new Player("b", "b", 100, 0, false));

            //Tables
            tableList = new List<Table>();
            tableList.Add(new Table(tableList.Count + 1, "Test table1", 20, 200, 0));
            tableList.Add(new Table(tableList.Count + 1, "Test table2", 20, 200, 0));

            //Moves
            moveList = new List<Move>();
        }


        public bool Login(string username, string password)
        {
            foreach (Player i in playerList)
            {
                if (username == i.Username && password == i.Password)
                {
                    return true;
                }
            }
            return false;
        }


        public bool Registration(string username, string password)
        {
            foreach (Player i in playerList)
            {
                if (username == i.Username)
                {
                    return false;
                }
            }
            playerList.Add(new Player(username, password, 0, 0, false));
            return true;
        }


        public int GetPlayerMoney(string username)
        {
            foreach (Player i in playerList)
            {
                if (username == i.Username)
                {
                    return i.Money;
                }
            }
            return 0;
        }


        public void TopUpMoney(string username, int amount)
        {
            foreach (Player i in playerList)
            {
                if (username == i.Username)
                {
                    i.Money += amount;
                }
            }
        }


        public void CreateTable(string tableName, int stackes, int minBuyIn)
        {
            tableList.Add(new Table(tableList.Count + 1, tableName, stackes, minBuyIn, 0));
        }


        public List<Table> GetTableList()
        {
            return tableList;
        }

        private Table getTable(int tabelId)
        {
            foreach (Table t in tableList)
            {
                if (t.TableID == tabelId)
                    return t;
            }
            return null;
        }


        public void TakeSeat(int tableId, int moneyOnTable, string username, int seatNr)
        {

            foreach (Player p in playerList)
            {
                if (p.Username == username)
                {
                    getTable(tableId).PlayingList.Add(p);
                    p.MoneyOnTable = moneyOnTable;
                    IGameCallBack gameCallBack = OperationContext.Current.GetCallbackChannel<IGameCallBack>();
                    p.PlayerCallBack = gameCallBack;
                    p.SeatNr = seatNr;
                    p.IsPlaying = true;
                    //p.Turn = seatNr;
                    foreach (Player x in getTable(tableId).PlayingList)
                    {
                        if (gameCallBack != x.PlayerCallBack)
                        {
                            x.PlayerCallBack.notifyOtherPlayers(p.Username, "takeSeat");
                            x.PlayerCallBack.updatePlayer(p.Username, moneyOnTable, p.SeatNr, p.IsYourTurn, p.Action);
                        }                        
                    }
                    break;
                }
            }
        }


        public List<Player> GetListOfPlayers(int tableId)
        {
            foreach (Table i in tableList)
            {
                if (i.TableID == tableId)
                {
                    return i.PlayingList;
                }
            }
            return null;
        }

        public void check(int tabelId, string username)
        {
            foreach (Player p in getTable(tabelId).PlayingList)
            {
                if (p.Username == username)
                {
                    //ToDo
                    p.IsYourTurn = false;
                    p.Action = "Check";
                    updatePlayers(tabelId, p.Username, p.MoneyOnTable, p.SeatNr, p.IsYourTurn, p.Action);
                }
                //IGameCallBack gameCallBack = OperationContext.Current.GetCallbackChannel<IGameCallBack>();

                //p.PlayerCallBack.updateCards(5, "♠", 1);
                //p.PlayerCallBack.updateCards(8, "♦", 2);
                //p.PlayerCallBack.updateCards(9, "♥", 3);
            }
        }


        public void call(int tabelId, string username)
        {
            foreach (Player p in getTable(tabelId).PlayingList)
            {
                if (p.Username == username)
                {
                    p.IsYourTurn = false;
                    p.Action = "Call";
                    updatePlayers(tabelId, p.Username, p.MoneyOnTable, p.SeatNr, p.IsYourTurn, p.Action);
                }
                p.PlayerCallBack.updatePot(getTable(tabelId).Pot);
            }
        }

        public void fold(int tabelId, string username)
        {
            foreach (Player p in getTable(tabelId).PlayingList)
            {
                if (p.Username == username)
                {
                    p.IsYourTurn = false;
                    p.IsPlaying = false;
                    p.Action = "Fold";
                    updatePlayers(tabelId, p.Username, p.MoneyOnTable, p.SeatNr, p.IsYourTurn, p.Action);
                }
                
            }
        }

        public void raise(int tabelId, string username, int amount)
        {
            foreach (Player p in getTable(tabelId).PlayingList)
            {
                if (p.Username == username)
                {
                    //ToDo
                    if (p.MoneyOnTable >= amount)
                    {
                        p.IsYourTurn = false;
                        getTable(tabelId).Pot += amount;
                        p.MoneyOnTable -= amount;
                        p.Action = "Raised " + amount;
                        updatePlayers(tabelId, p.Username, p.MoneyOnTable, p.SeatNr, p.IsYourTurn, p.Action);
                    }
                }
                p.PlayerCallBack.updatePot(getTable(tabelId).Pot);
            }
        }

        private void updatePlayers(int tableid, string username, int money, int seatNr, bool turn, string action)
        {
            foreach (Player p in getTable(tableid).PlayingList)
            {
                p.PlayerCallBack.updatePlayer(username, money, seatNr, turn, action);
            }
        }
    }
}
